package com.common.oss.service;

import com.aliyun.oss.OSS;
import com.aliyun.oss.model.GetObjectRequest;
import com.aliyun.oss.model.PutObjectRequest;
import com.common.oss.exception.OssBaseException;
import com.common.oss.exception.OssExceptionMsg;
import com.common.oss.instance.OssInstance;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.UUID;

/**
 * Oss服务调用
 */
@Service
public class OssService {

    private OSS ossClient ;

    private String bucketName;

    private String accessPre ;

    public OssService(OssInstance ossInstance) {
        if (ossInstance == null){
            throw new OssBaseException(OssExceptionMsg.OSS_FAIL_MSG);
        }
        this.ossClient = ossInstance.getOssClient();
        this.bucketName = ossInstance.getBucketName();
        this.accessPre = ossInstance.getAccessPre() + "/";
    }

    /**
     * 默认路径上传本地文件
     * @param filePath
     */
    public String uploadFile(String filePath){
        return uploadFileForBucket(this.bucketName,getOssFilePath(filePath) ,filePath);
    }

    /**
     * 默认路径上传multipartFile文件
     * @param multipartFile
     */
    public String uploadMultipartFile(MultipartFile multipartFile) {
        return uploadMultipartFile(this.bucketName,getOssFilePath(multipartFile.getOriginalFilename()),multipartFile);
    }

    /**
     * 上传 multipartFile 类型文件
     * @param bucketName
     * @param ossPath
     * @param multipartFile
     */
    public String uploadMultipartFile(String bucketName , String ossPath , MultipartFile multipartFile){
        InputStream inputStream = null;
        try {
            inputStream = multipartFile.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
            throw new OssBaseException(e.getMessage());
        }
        uploadFileInputStreamForBucket(bucketName, ossPath, inputStream);
        return this.accessPre+ossPath;
    }

    /**
     * 使用File上传PutObject上传文件 ** 程序默认使用次方法上传
     * @param bucketName 实例名称
     * @param ossPath oss存储路径
     * @param filePath 本地文件路径
     */
    public String uploadFileForBucket(String bucketName , String ossPath , String filePath) {
        // 判断 bucket是否存在
        if (StringUtils.isEmpty(bucketName)){
            bucketName = this.bucketName;
        }
        // 校验oss存储路径
        if (StringUtils.isEmpty(ossPath)){
            throw new OssBaseException(OssExceptionMsg.OSS_FILE_PATH_NOT_NULL);
        }
        //校验本地文件存储路径
        if (StringUtils.isEmpty(filePath)){
            throw new OssBaseException(OssExceptionMsg.LOCAL_FILE_PATH_NOT_NULL);
        }
        // 创建PutObjectRequest对象。
        PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, ossPath, new File(filePath));

        // 上传
        ossClient.putObject(putObjectRequest);
        return this.accessPre+ossPath;
    }

    /**
     * 使用文件流上传到指定的bucket实例
     * @param bucketName 实例名称
     * @param ossPath oss存储路径
     * @param filePath 本地文件路径
     */
    public String uploadFileInputStreamForBucket(String bucketName , String ossPath , String filePath){

        //校验本地文件存储路径
        if (StringUtils.isEmpty(filePath)){
            throw new OssBaseException(OssExceptionMsg.LOCAL_FILE_PATH_NOT_NULL);
        }
        // 填写本地文件的完整路径。如果未指定本地路径，则默认从示例程序所属项目对应本地路径中上传文件流。
        InputStream inputStream = null;
        try {
            inputStream = new FileInputStream(filePath);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            throw new OssBaseException(e.getMessage());
        }
        // 填写Bucket名称和Object完整路径。Object完整路径中不能包含Bucket名称。
        uploadFileInputStreamForBucket(bucketName, ossPath, inputStream);
        return this.accessPre+ossPath;
    }

    public void uploadFileInputStreamForBucket(String bucketName , String ossPath , InputStream inputStream ){
        // 判断 bucket是否存在
        if (StringUtils.isEmpty(bucketName)){
            bucketName = this.bucketName;
        }
        // 校验oss存储路径
        if (StringUtils.isEmpty(ossPath)){
            throw new OssBaseException(OssExceptionMsg.OSS_FILE_PATH_NOT_NULL);
        }
        ossClient.putObject(bucketName, ossPath, inputStream);
    }

    /**
     * 下载
     * @param ossFilePath
     * @param filePath
     */
    public void downloadFile(String ossFilePath , String filePath ){
        downloadFileForBucket(this.bucketName , ossFilePath , filePath);
    }
    /**
     * 下载
     * @param bucketName 实例名称
     * @param ossFilePath oss存储路径
     * @param filePath 本地文件路径
     */
    public void downloadFileForBucket(String bucketName , String ossFilePath , String filePath ){
        // 判断 bucket是否存在
        if (StringUtils.isEmpty(bucketName)){
            bucketName = this.bucketName;
        }
        // 校验oss存储路径
        if (StringUtils.isEmpty(ossFilePath)){
            throw new OssBaseException(OssExceptionMsg.OSS_FILE_PATH_NOT_NULL);
        }
        //校验本地文件存储路径
        if (StringUtils.isEmpty(filePath)){
            throw new OssBaseException(OssExceptionMsg.LOCAL_FILE_PATH_NOT_NULL);
        }
        ossClient.getObject(new GetObjectRequest(bucketName, ossFilePath), new File(filePath));
    }

    public String getOssDefaultPath(){
        LocalDateTime now = LocalDateTime.now();
        String url =
                now.getYear()+"/"+
                now.getMonth()+"/"+
                now.getDayOfMonth()+"/"+
                now.getHour()+"/"+
                now.getMinute()+"/";
        return url;
    }

    public String getOssFilePath(String filePath){
        String fileSuf = filePath.substring(filePath.indexOf(".") + 1);
        return getOssDefaultPath() + UUID.randomUUID().toString() + "." + fileSuf;
    }


}
